% 仿真qpsk调制的基带数字信号经过awgn信道，通过m序列进行扩频和解扩，计算误码率和误符号率
clear all;              %清空工作区变量
nSamp = 8;              %矩形脉冲的取样点数
numSymb = 10000;        %每种SNR下的传输的符号数
M=4;                    %QPSK的符号类型数
SNR=-30:3;              %SNR的范围
grayencod=[0 1 3 2];    %Gray编码格式

% 13位M序列
mseq = [1 1 1 0 1 0 0 1 1 1 0 1 0];
for i = 1:6
    mseq = [mseq mseq(i)];
end

% 13位barker序列
barker = [1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1];

% 13位巴克码偶序列
barker_pair_x = [-1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1];
barker_pair_y = [-1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1];

% 18位巴克码偶序列
barker_pair_x2 = [1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1];
barker_pair_y2 = [1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1];

% 21位巴克码偶序列
barker_pair_x3 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1];
barker_pair_y3 = [-1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1];

% 循环遍历每种SNR
for ii=1:length(SNR)
    msg=randsrc(1,numSymb,0:3);             %产生发送符号
    msg_gr=grayencod(msg+1);                %进行Gray编码映射
    msg_tx=pskmod(msg_gr,M);                %QPSK调制


    % ==========不进行扩频==========
    msg_tx_sp_no = msg_tx;

    % ==========使用m序列进行扩频==========
    msg_tx_sp_mseq = zeros(1, length(msg_tx) * length(mseq)); %初始化扩频后的信号
    for j = 1:length(msg_tx)
        msg_tx_sp_mseq((j-1)*length(mseq)+1:j*length(mseq)) = mseq.*msg_tx(j); %扩频
    end
    % ==========使用巴克序列进行扩频==========
    msg_tx_sp_barker = zeros(1, length(msg_tx) * length(barker)); %初始化扩频后的信号
    for j = 1:length(msg_tx)
        msg_tx_sp_barker((j-1)*length(barker)+1:j*length(barker)) = barker.*msg_tx(j); %扩频
    end

    % ==========使用巴克码偶进行扩频==========
    msg_tx_sp_barker_pair = zeros(1, length(msg_tx) * length(barker_pair_x)); %初始化扩频后的信号
    for j = 1:length(msg_tx)
        msg_tx_sp_barker_pair((j-1)*length(barker_pair_x)+1:j*length(barker_pair_x)) = barker_pair_x.*msg_tx(j); %扩频
    end

    % ==========使用巴克码偶进行扩频==========
    msg_tx_sp_barker_pair2 = zeros(1, length(msg_tx) * length(barker_pair_x2)); %初始化扩频后的信号
    for j = 1:length(msg_tx)
        msg_tx_sp_barker_pair2((j-1)*length(barker_pair_x2)+1:j*length(barker_pair_x2)) = barker_pair_x2.*msg_tx(j); %扩频
    end

    % ==========使用巴克码偶进行扩频==========
    msg_tx_sp_barker_pair3 = zeros(1, length(msg_tx) * length(barker_pair_x3)); %初始化扩频后的信号
    for j = 1:length(msg_tx)
        msg_tx_sp_barker_pair3((j-1)*length(barker_pair_x3)+1:j*length(barker_pair_x3)) = barker_pair_x3.*msg_tx(j); %扩频
    end

    

    msg_tx_sp_no = rectpulse(msg_tx_sp_no,nSamp);               %矩形脉冲成形
    msg_tx_sp_mseq = rectpulse(msg_tx_sp_mseq,nSamp);           %矩形脉冲成形
    msg_tx_sp_barker = rectpulse(msg_tx_sp_barker,nSamp);       %矩形脉冲成形
    msg_tx_sp_barker_pair = rectpulse(msg_tx_sp_barker_pair,nSamp);       %矩形脉冲成形
    msg_tx_sp_barker_pair2 = rectpulse(msg_tx_sp_barker_pair2,nSamp);       %矩形脉冲成形
    msg_tx_sp_barker_pair3 = rectpulse(msg_tx_sp_barker_pair3,nSamp);       %矩形脉冲成形

    msg_rx_sp_no = awgn(msg_tx_sp_no,SNR(ii),'measured');       %通过AWGN信道
    msg_rx_sp_mseq = awgn(msg_tx_sp_mseq,SNR(ii),'measured');   %通过AWGN信道
    msg_rx_sp_barker=awgn(msg_tx_sp_barker,SNR(ii),'measured'); %通过AWGN信道
    msg_rx_sp_barker_pair=awgn(msg_tx_sp_barker_pair,SNR(ii),'measured'); %通过AWGN信道
    msg_rx_sp_barker_pair2=awgn(msg_tx_sp_barker_pair2,SNR(ii),'measured'); %通过AWGN信道
    msg_rx_sp_barker_pair3=awgn(msg_tx_sp_barker_pair3,SNR(ii),'measured'); %通过AWGN信道

    % ==========使用匹配滤波器进行相干解调==========
    msg_rx_down_sq_no = intdump(msg_rx_sp_no,nSamp);            %匹配滤波相干解调
    msg_rx_down_sp_mseq = intdump(msg_rx_sp_mseq,nSamp);        %匹配滤波相干解调
    msg_rx_down_sp_barker=intdump(msg_rx_sp_barker,nSamp);      %匹配滤波相干解调
    msg_rx_down_sp_barker_pair=intdump(msg_rx_sp_barker_pair,nSamp);      %匹配滤波相干解调
    msg_rx_down_sp_barker_pair2=intdump(msg_rx_sp_barker_pair2,nSamp);      %匹配滤波相干解调
    msg_rx_down_sp_barker_pair3=intdump(msg_rx_sp_barker_pair3,nSamp);      %匹配滤波相干解调
    
    % ==========无需进行解扩==========
    msg_rx_desq_no = msg_rx_down_sq_no;

    % ==========使用m序列进行解扩==========
    msg_rx_desq_mseq = zeros(1, length(msg_rx_down_sp_mseq)/length(mseq)); %初始化扩频后的接收信号
    for j = 1:length(msg_rx_desq_mseq)
        msg_rx_desq_mseq(j) = sum(msg_rx_down_sp_mseq((j-1)*length(mseq)+1:j*length(mseq)).*mseq); %去扩频
    end

    % ==========使用巴克序列进行解扩==========
    msg_rx_desq_barker= zeros(1, length(msg_rx_down_sp_barker)/length(barker)); %初始化扩频后的接收信号
    for j = 1:length(msg_rx_desq_barker)
        msg_rx_desq_barker(j) = sum(msg_rx_down_sp_barker((j-1)*length(barker)+1:j*length(barker)).*barker); %去扩频
    end

    % ==========使用巴克码偶进行解扩==========
    msg_rx_desq_barker_pair= zeros(1, length(msg_rx_down_sp_barker_pair)/length(barker_pair_y)); %初始化扩频后的接收信号
    for j = 1:length(msg_rx_desq_barker_pair)
        msg_rx_desq_barker_pair(j) = sum(msg_rx_down_sp_barker_pair((j-1)*length(barker_pair_y)+1:j*length(barker_pair_y)).*barker_pair_y); %去扩频
    end

    % ==========使用巴克码偶进行解扩==========
    msg_rx_desq_barker_pair2= zeros(1, length(msg_rx_down_sp_barker_pair2)/length(barker_pair_y2)); %初始化扩频后的接收信号
    for j = 1:length(msg_rx_desq_barker_pair2)
        msg_rx_desq_barker_pair2(j) = sum(msg_rx_down_sp_barker_pair2((j-1)*length(barker_pair_y2)+1:j*length(barker_pair_y2)).*barker_pair_y2); %去扩频
    end

    % ==========使用巴克码偶进行解扩==========
    msg_rx_desq_barker_pair3= zeros(1, length(msg_rx_down_sp_barker_pair3)/length(barker_pair_y3)); %初始化扩频后的接收信号
    for j = 1:length(msg_rx_desq_barker_pair3)
        msg_rx_desq_barker_pair3(j) = sum(msg_rx_down_sp_barker_pair3((j-1)*length(barker_pair_y3)+1:j*length(barker_pair_y3)).*barker_pair_y3); %去扩频
    end

    % ==========QPSK解调==========
    msg_gr_demod_no = pskdemod(msg_rx_desq_no,M);
    msg_gr_demod_mseq = pskdemod(msg_rx_desq_mseq,M);
    msg_gr_demod_barker = pskdemod(msg_rx_desq_barker,M);
    msg_gr_demod_barker_pair = pskdemod(msg_rx_desq_barker_pair,M);
    msg_gr_demod_barker_pair2 = pskdemod(msg_rx_desq_barker_pair2,M);
    msg_gr_demod_barker_pair3 = pskdemod(msg_rx_desq_barker_pair3,M);

    [dummy, graydecod] = sort(grayencod); 
    graydecod = graydecod - 1;

    % ==========Gray编码逆映射==========
    msg_demod_no = graydecod(msg_gr_demod_no+1); % Gray编码逆映射
    msg_demod_mseq = graydecod(msg_gr_demod_mseq+1); % Gray编码逆映射
    msg_demod_barker = graydecod(msg_gr_demod_barker+1); % Gray编码逆映射
    msg_demod_barker_pair = graydecod(msg_gr_demod_barker_pair+1); % Gray编码逆映射
    msg_demod_barker_pair2 = graydecod(msg_gr_demod_barker_pair2+1); % Gray编码逆映射
    msg_demod_barker_pair3 = graydecod(msg_gr_demod_barker_pair3+1); % Gray编码逆映射


    [errorBit_no, BER_no(ii)] = biterr(msg, msg_demod_no, log2(M)); %计算BER
    [errorSym_no, SER_no(ii)] = symerr(msg, msg_demod_no);          %计算SER
    [errorBit_mseq, BER_mseq(ii)] = biterr(msg, msg_demod_mseq, log2(M)); %计算BER
    [errorSym_mseq, SER_mseq(ii)] = symerr(msg, msg_demod_mseq);          %计算SER
    [errorBit_barker, BER_barker(ii)] = biterr(msg, msg_demod_barker, log2(M)); %计算BER
    [errorSym_barker, SER_barker(ii)] = symerr(msg, msg_demod_barker);          %计算SER
    [errorBit_barker_pair, BER_barker_pair(ii)] = biterr(msg, msg_demod_barker_pair, log2(M)); %计算BER
    [errorSym_barker_pair, SER_barker_pair(ii)] = symerr(msg, msg_demod_barker_pair);          %计算SER
    [errorBit_barker_pair2, BER_barker_pair2(ii)] = biterr(msg, msg_demod_barker_pair2, log2(M)); %计算BER
    [errorSym_barker_pair2, SER_barker_pair2(ii)] = symerr(msg, msg_demod_barker_pair2);          %计算SER
    [errorBit_barker_pair3, BER_barker_pair3(ii)] = biterr(msg, msg_demod_barker_pair3, log2(M)); %计算BER
    [errorSym_barker_pair3, SER_barker_pair3(ii)] = symerr(msg, msg_demod_barker_pair3);          %计算SER
end

% 画出发射信号和接收信号的星座图
scatterplot(msg_tx(1:100))                  
title('发射信号星座图')
xlabel('同相分量')
ylabel('正交分量')
scatterplot(msg_rx_desq_no(1:100))                  
title('接收信号星座图-不进行扩频')
xlabel('同相分量')
ylabel('正交分量')
scatterplot(msg_rx_desq_mseq(1:100))                  
title('接收信号星座图-m序列进行扩频')
xlabel('同相分量')
ylabel('正交分量')
% scatterplot(msg_rx_desq_barker(1:100))                  
% title('接收信号星座图-巴克序列进行扩频')
% xlabel('同相分量')
% ylabel('正交分量')
% scatterplot(msg_rx_desq_barker_pair(1:100))                  
% title('接收信号星座图-巴克码偶进行扩频')
% xlabel('同相分量')
% ylabel('正交分量')
% scatterplot(msg_rx_desq_barker_pair2(1:100))                  
% title('接收信号星座图-巴克码偶2进行扩频')
% xlabel('同相分量')
% ylabel('正交分量')

% 画出BER和SER随SNR变化的曲线
figure
semilogy(SNR, BER_no,'-o', ...
         SNR, BER_mseq,'-p', ...
         SNR, BER_barker,'-x', ...
         SNR, BER_barker_pair,'-v', ...
         SNR, BER_barker_pair2,'-+', ...
         SNR, BER_barker_pair3,'-s');
legend('不进行扩频', ...
       'm序列', ...
       '巴克码', ...
       '巴克码偶', ...
       '巴克码偶2', ...
       '巴克码偶3');
title('QPSK在AWGN信道下的性能')
xlabel('信噪比（dB）')
ylabel('误比特率')

figure
semilogy(SNR, SER_no,'-o', ...
         SNR, SER_mseq,'-p', ...
         SNR, SER_barker,'-x', ...
         SNR, SER_barker_pair,'-v', ...
         SNR, SER_barker_pair2,'-+', ...
         SNR, SER_barker_pair3,'-s');
legend('不进行扩频', ...
       'm序列', ...
       '巴克码', ...
       '巴克码偶', ...
       '巴克码偶2', ...
       '巴克码偶3');
title('QPSK在AWGN信道下的性能')
xlabel('信噪比（dB）')
ylabel('误符号率')